package com.find.answer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.find.answer.domain.dto.DishDto;
import com.find.answer.domain.dto.PageDto;
import com.find.answer.domain.po.Category;
import com.find.answer.domain.po.Dish;
import com.find.answer.domain.po.DishFlavor;
import com.find.answer.mapper.DishMapper;
import com.find.answer.service.CategoryService;
import com.find.answer.service.DishFlavorService;
import com.find.answer.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 该类下所有方法均已经开启事务。
 * @author Seon
 * @date 2022/10/25 15:21
 */
@Service
@Transactional
public class DishServiceImpl
        extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Override
    public Page<DishDto> getDishDtoPage(PageDto answer, String name) {
        Page<Dish> dishPage = new Page<>();
        Page<DishDto> dishDtoPage = new Page<>();
        dishPage.setCurrent(answer.getPage());
        dishPage.setSize(answer.getPageSize());
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(name != null, Dish::getName, name);
        wrapper.orderByDesc(Dish::getUpdateTime);
        this.page(dishPage, wrapper);
        BeanUtils.copyProperties(dishPage, dishDtoPage, "records");

        /*
        使用流二次加载了一下集合里的数据。
         */
        List<Dish> records = dishPage.getRecords();
        List<DishDto> list = records.stream().map(items -> {
            Long id = items.getCategoryId();
            Category category = categoryService.getById(id);
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(items, dishDto);
            dishDto.setCategoryName(category.getName());
            return dishDto;
        }).collect(Collectors.toList());

        dishDtoPage.setRecords(list);
        return dishDtoPage;
    }

    @Override
    public boolean saveWithFlavors(DishDto dishDto) {
        try {
            this.save(dishDto);
            Long dishId = dishDto.getId();
            List<DishFlavor> flavors = dishDto.getFlavors();
            // 使用peek来转
            // todo: 流编程需要留时间来学习。
            flavors = flavors.stream().peek(items -> items.setDishId(dishId)).collect(Collectors.toList());
            dishFlavorService.saveBatch(flavors);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    @Override
    public DishDto getWithFlavors(Long dishId) {
        Dish dish = this.getById(dishId);
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish, dishDto);

        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DishFlavor::getDishId, dishId);
        List<DishFlavor> list = dishFlavorService.list(wrapper);
        dishDto.setFlavors(list);
        return dishDto;
    }

    @Override
    public boolean updateWithFlavors(DishDto dishDto) {
        /*
        第一步先把Dish的数据更新进去。
        第二步把原本的DishFlavors删除掉。
        第三步，插入新的DishFlavors数据。
         */
        this.updateById(dishDto);

        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DishFlavor::getDishId, dishDto.getId());
        dishFlavorService.remove(wrapper);

        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors = flavors.stream().map(items -> {
            items.setDishId(dishDto.getId());
            return items;
        }).collect(Collectors.toList());
        dishFlavorService.saveBatch(flavors);
        return true;
    }

    @Override
    public boolean deleteWithFlavors(List<Long> ids) {
        this.removeByIds(ids);
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        ids.forEach(id -> {
            wrapper.eq(DishFlavor::getDishId, id);
            dishFlavorService.remove(wrapper);
        });
        return true;
    }
}
